/*
 * Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef VIRTNET_DEVX_H
#define VIRTNET_DEVX_H

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>

#include <infiniband/verbs.h>
#include <infiniband/mlx5dv.h>

#include "virtnet_sf.h"

#ifdef __cplusplus
extern "C" {
#endif

struct mlx_devx_wq_attr {
	uint32_t wq_type:4;
	uint32_t wq_signature:1;
	uint32_t end_padding_mode:2;
	uint32_t cd_slave:1;
	uint32_t hds_skip_first_sge:1;
	uint32_t log2_hds_buf_size:3;
	uint32_t page_offset:5;
	uint32_t lwm:16;
	uint32_t pd:24;
	uint32_t uar_page:24;
	uint64_t dbr_addr;
	uint32_t hw_counter;
	uint32_t sw_counter;
	uint32_t log_wq_stride:4;
	uint32_t log_wq_pg_sz:5;
	uint32_t log_wq_sz:5;
	uint32_t dbr_umem_valid:1;
	uint32_t wq_umem_valid:1;
	uint32_t log_hairpin_num_packets:5;
	uint32_t log_hairpin_data_sz:5;
	uint32_t single_wqe_log_num_of_strides:4;
	uint32_t two_byte_shift_en:1;
	uint32_t single_stride_log_num_of_bytes:3;
	uint32_t dbr_umem_id;
	uint32_t wq_umem_id;
	uint64_t wq_umem_offset;
};

/* Create RQ attributes structure, used by create RQ operation. */
struct mlx_devx_create_rq_attr {
	uint32_t rlky:1;
	uint32_t delay_drop_en:1;
	uint32_t scatter_fcs:1;
	uint32_t vsd:1;
	uint32_t mem_rq_type:4;
	uint32_t state:4;
	uint32_t flush_in_error_en:1;
	uint32_t hairpin:1;
	uint32_t user_index:24;
	uint32_t cqn:24;
	uint32_t counter_set_id:8;
	uint32_t rmpn:24;
	struct mlx_devx_wq_attr wq_attr;
};

struct mlx_devx_rqt_attr {
	uint8_t rq_type;
	uint32_t max_size:16;
	uint32_t actual_size:16;
	uint32_t rq_list[];
};

void *mlx_devx_td_create(struct ibv_context *dev, uint32_t *td_id);
void *mlx_devx_tis_create(struct ibv_context *dev, uint32_t td_id,
			  uint32_t *tis_id);
int mlx_devx_obj_destroy(struct mlx5dv_devx_obj *obj);
struct ibv_context *mlx_dv_open_device(const char *name,
				       struct mlx5dv_context_attr *attr);
void *mlx_devx_rqt_create(struct ibv_context *dev,
			  struct mlx_devx_rqt_attr *rqt_attr,
			  uint32_t *rqt_id);
int mlx_devx_rqt_modify(struct mlx5dv_devx_obj *rqt, int rqtn,
			struct mlx_devx_rqt_attr *rqt_attr);
void *mlx_devx_cmd_create_tir(struct ibv_context *ctx,
			      struct virtnet_tir_devx_attr *tir_attr,
			      uint32_t *tir_id);
int mlx_devx_match_lyr_2_4_new(struct mlx5dv_flow_match_parameters **mask,
			       struct mlx5dv_flow_match_parameters **value);
void
mlx_devx_match_lyr_2_4_delete(struct mlx5dv_flow_match_parameters *mask,
			      struct mlx5dv_flow_match_parameters *value);
int mlx_devx_match_lyr_2_4_init(uint8_t ip_version, uint8_t ip_proto,
				struct mlx5dv_flow_match_parameters *mask,
				struct mlx5dv_flow_match_parameters *value);
void mlx_devx_match_set_mac_dst(uint8_t *addr_m, uint8_t *addr_v,
				struct mlx5dv_flow_match_parameters *mask,
				struct mlx5dv_flow_match_parameters *value);
struct mlx5dv_devx_obj *
mlx_devx_create_flow_table(struct ibv_context *ctx,
			   uint32_t type, uint8_t level,
			   uint8_t log_size, uint32_t *id);
struct mlx5dv_devx_obj*
mlx_devx_create_rq(struct ibv_context *ctx,
		   struct mlx_devx_create_rq_attr *rq_attr,
		   uint32_t *rqn);
#ifdef __cplusplus
}
#endif

#endif
